package service;

import dao.*;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import pojo.CheckInRecord;
import pojo.CheckOutRecord;
import utils.JDBCUtils;
import utils.SystemEnum;

import java.math.BigDecimal;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Date;

public class CheckInRecordServiceImpl implements CheckInRecordService{
    private Connection con = null;
    private CheckInRecordDao dao = new CheckInRecordDaoImpl();
    private BedDaoImpl bedDao = new BedDaoImpl();
    private BedServiceImpl bedService = new BedServiceImpl();
    private StudentDao studentDao = new StudentDaoImpl();

    private Log log = LogFactory.getLog(getClass());
    @Override
    public ArrayList<CheckInRecord> findAll() {
        return dao.findAll();
    }

    @Override
    public int findTotal() {
        return dao.findAll().size();
    }

    @Override
    public int findDate(Date begin, Date end) {
        ArrayList<CheckInRecord> list = dao.findAll();
        ArrayList<CheckInRecord> checkInRecords = new ArrayList<CheckInRecord>();
        for (CheckInRecord checkInRecord : list) {
            if((checkInRecord.getCherk_in_time().after(begin)&&checkInRecord.getCherk_in_time().before(end))||checkInRecord.getCherk_in_time().equals(begin)||checkInRecord.getCherk_in_time().equals(end)){
                checkInRecords.add(checkInRecord);
            }
        }
        return checkInRecords.size();
    }

    @Override
    public BigDecimal findActualPayment() {
        ArrayList<CheckInRecord> list = dao.findAll();
        BigDecimal sum = new BigDecimal(0);
        for (CheckInRecord checkInRecord : list) {
            sum = sum.add(checkInRecord.getActual_payment());
        }
        return sum;
    }

    @Override
    public BigDecimal findNoPay() {
        ArrayList<CheckInRecord> list = dao.findAll();
        BigDecimal sum = new BigDecimal(0);
        for (CheckInRecord checkInRecord : list) {
            sum = sum.add(checkInRecord.getPayment()).subtract(checkInRecord.getActual_payment());
        }
        return sum;
    }

    @Override
    public BigDecimal findPaymentInTime(Date begin, Date end) {
        ArrayList<CheckInRecord> list = dao.findAll();
        BigDecimal sum = new BigDecimal(0);
        for (CheckInRecord checkInRecord : list) {
            if((checkInRecord.getCherk_in_time().after(begin)&&checkInRecord.getCherk_in_time().before(end))||checkInRecord.getCherk_in_time().equals(begin)||checkInRecord.getCherk_in_time().equals(end)){
                sum = sum.add(checkInRecord.getPayment());
            }
        }
        return sum;
    }

    @Override
    public BigDecimal findActualPaymentInTime(Date begin, Date end) {
        ArrayList<CheckInRecord> list = dao.findAll();
        BigDecimal sum = new BigDecimal(0);
        for (CheckInRecord checkInRecord : list) {
            if((checkInRecord.getCherk_in_time().after(begin)&&checkInRecord.getCherk_in_time().before(end))||checkInRecord.getCherk_in_time().equals(begin)||checkInRecord.getCherk_in_time().equals(end)){
                sum = sum.add(checkInRecord.getActual_payment());
            }
        }
        return sum;
    }

    @Override
    public BigDecimal findNoPayInTime(Date begin, Date end) {
        ArrayList<CheckInRecord> list = dao.findAll();
        BigDecimal sum = new BigDecimal(0);
        for (CheckInRecord checkInRecord : list) {
            if((checkInRecord.getCherk_in_time().after(begin)&&checkInRecord.getCherk_in_time().before(end))||checkInRecord.getCherk_in_time().equals(begin)||checkInRecord.getCherk_in_time().equals(end)){
                sum = sum.add(checkInRecord.getPayment()).subtract(checkInRecord.getActual_payment());
            }
        }
        return sum;
    }

    @Override
    public BigDecimal findCashInTime(Date begin, Date end) {
        ArrayList<CheckInRecord> list = dao.findAll();
        BigDecimal sum = new BigDecimal(0);
        for (CheckInRecord checkInRecord : list) {
            if((checkInRecord.getCherk_in_time().after(begin)&&checkInRecord.getCherk_in_time().before(end))||checkInRecord.getCherk_in_time().equals(begin)||checkInRecord.getCherk_in_time().equals(end)){
                sum = sum.add(checkInRecord.getPayedCash());
            }
        }
        return sum;
    }

    @Override
    public ArrayList<CheckInRecord> findArrearage() {
        ArrayList<CheckInRecord> list = dao.findAll();
        ArrayList<CheckInRecord> checkInRecord = new ArrayList<CheckInRecord>();
        for (CheckInRecord checkInRecord1 : list) {
            if((checkInRecord1.getPayment().subtract(checkInRecord1.getActual_payment()).compareTo(BigDecimal.ZERO) > 0)){
                checkInRecord.add(checkInRecord1);
            }
        }
        return checkInRecord;
    }

    @Override
    public ArrayList<CheckInRecord> findIsTaken() {
        ArrayList<CheckInRecord> list = dao.findAll();
        ArrayList<CheckInRecord> checkInRecord = new ArrayList<CheckInRecord>();
        for (CheckInRecord checkInRecord1 : list) {
            if(checkInRecord1.isTakenKey()){
                checkInRecord.add(checkInRecord1);
            }
        }
        return checkInRecord;
    }

    @Override
    public ArrayList<CheckInRecord> findNoTaken() {
        ArrayList<CheckInRecord> list = dao.findAll();
        ArrayList<CheckInRecord> checkInRecord = new ArrayList<CheckInRecord>();
        for (CheckInRecord checkInRecord1 : list) {
            if(!checkInRecord1.isTakenKey()){
                checkInRecord.add(checkInRecord1);
            }
        }
        return checkInRecord;
    }

    @Override
    public ArrayList<CheckInRecord> findByRoomId(Integer roomId) {
        ArrayList<CheckInRecord> list = dao.findAll();
        ArrayList<CheckInRecord> checkInRecord = new ArrayList<CheckInRecord>();
        for (CheckInRecord checkInRecord1 : list) {
            if(checkInRecord1.getDormId()==roomId){
                checkInRecord.add(checkInRecord1);
            }
        }
        return checkInRecord;
    }

    @Override
    public CheckInRecord findById(Integer check_in_id) {
        return dao.findById(check_in_id);
    }

    @Override
    public CheckInRecord findByStuId(Integer stuId) {
        ArrayList<CheckInRecord> list = dao.findAll();
        CheckInRecord checkInRecord = new CheckInRecord();
        for (CheckInRecord checkInRecord1 : list) {
            if(checkInRecord1.getStuId() == stuId){
                checkInRecord = checkInRecord1;
            }
        }
        return checkInRecord;
    }

    @Override
    public CheckInRecord findByStuName(String stuName) {
        ArrayList<CheckInRecord> list = dao.findAll();
        CheckInRecord checkInRecord = new CheckInRecord();
        for (CheckInRecord checkInRecord1 : list) {
            if(checkInRecord1.getStuId() == studentDao.findByStuName(stuName).getStuId()){
                checkInRecord = checkInRecord1;
            }
        }
        return checkInRecord;
    }


    @Override
    public int insert(CheckInRecord check_in_id) {

        try {
            con = JDBCUtils.getConnection();
            con.setAutoCommit(false);

            int row1 = dao.insert(con,check_in_id);

            //无人居住--转换床铺状态
            int row2  = bedDao.update(con,bedService.findById(check_in_id.getDormId(),check_in_id.getBedId()));

            if(row1 >0 &&row2 > 0){
                con.commit();
                return row1 + row2;
            }else{
                con.rollback();
            }
        } catch (SQLException e) {
            e.printStackTrace();
            log.info(SystemEnum.ERROR_INEFFECTIVE+"\t正在回滚");
            try {
                con.rollback();
            } catch (SQLException ex) {
                ex.printStackTrace();
                log.info("回滚\t"+SystemEnum.ERROR_INEFFECTIVE);
            }
        } finally {
            try {
                con.setAutoCommit(true);
            } catch (SQLException e) {
                e.printStackTrace();
            }
            JDBCUtils.close(con,null);
            log.info(SystemEnum.END);
        }
        return 0;

    }

    @Override
    public int update(CheckInRecord check_in_id) {
        return dao.update(check_in_id);
    }

    @Override
    public int delete(CheckInRecord check_in_id) {
        return dao.delete(check_in_id);
    }
}
